<?php
/**
 * response for a ajax panel request
 */
fily_XMLConverter::registerNamespace('ajaxresponse', fily_AjaxResponse);
class fily_AjaxResponse implements fily_ControlToHtml, fily_XMLToControl {

    /**
     * inner html controls
     * @var fily_ControlList
     */
    public $controls;

    /**
     * id for this control
     * @var <type>
     */
    protected $id;

    /**
     * array that contains all triggerobjects
     * @var array
     */
    protected $updateTriggers = array();

    /**
     * path to file for the ajax request
     * @var string
     */
    protected $requestFile = '';

    /**
     * control that triggered the ajax request
     * @var fily_Control
     */
    protected $triggerControl = null;

    /**
     * event that triggered the ajax request
     * @var string
     */
    protected $triggerEvent = '';

    /**
     * the value of the trigger
     * @var string
     */
    protected $triggerValue = '';
    /**
     *
     */
    public function __construct() {
        $this->id = $_REQUEST['firelynx_ajaxContainerId'];
        $this->controls = new fily_ControlList();
        $this->controls->setParent($this);
        $this->requestFile = $_REQUEST['firelynx_ajaxContainerRequestFile'];
        $this->triggerControl = new fily_Control(strtolower($_REQUEST['firelynx_ajaxContainerTriggerControlTag']));
        foreach($_REQUEST['firelynx_ajaxContainerTriggerControl'] as $key => $value) {
            $this->triggerControl->attributes->set($key, $value);
        }
        $this->triggerEvent = $_REQUEST['firelynx_ajaxContainerTriggerEvent'];
        $this->triggerValue = $_REQUEST['firelynx_ajaxContainerTriggerControlValue'];
    }

    /**
     * returns the id for this control
     * @return string
     */
    public function getId() {
        return $this->id;
    }

          /**
     * system id
     * @var string
     */
    protected $sid;
    /**
     * system id
     * @return string
     */
    public function getSid(){
        return $this->sid;
    }

    /**
     * system id
     * @param string $sid
     */
    public function setSid($sid){
        $this->sid = $sid;
    }


    /**
     * generate the html
     */
    public function toHtml() {
        $this->prepare();
        $html =  $this->controls->toHtml();
        $js = fily_ClientCodeManager::getClientCode();
        return $js . '~-#-#-#-~firelynx_AjaxContainerResponse~-#-#-#-~' .$html;
    }

    /**
     * shortcut for toHtml()
     */
    public function __toString() {
        return $this->toHtml();
    }


    /**
     * prepares the code for the html output
     */
    public function prepare() {
        // add client code
        foreach ($this->updateTriggers as $updateTrigger) {
            $code = sprintf("firelynx.findClientObject('%s_AjaxContainer').addTrigger('%s', '%s', %s);", $this->getId(), $updateTrigger['control']->getId(),  $updateTrigger['event'], $updateTrigger['executionZone']);
            fily_ClientCodeManager::addCode($code);
            fily_ClientCodeManager::useId($updateTrigger['control']->getId());
        }
        // prepare inner controls
        $this->controls->prepare();
    }
    /**
     * Add a trigger for an ajax request
     * @param fily_Control $triggerControl the control that triggers the event
     * @param string $triggerEvent javascript event (onclick, onchange)
     * @param int $executionZone
     */
    public function addUpdateTrigger(fily_Control $triggerControl, $triggerEvent, $executionZone = 800) {
        $this->updateTriggers[] = array('control' => $triggerControl, 'event' => $triggerEvent,  'executionZone' => $executionZone);
    }




    /**
     * get the path for the ajax request file
     * @return string
     */
    public function getRequestFile() {
        return $this->requestFile;
    }

    /**
     * set the path to the ajax request file
     * @param string $value
     */
    public function setRequestFile($value) {
        $this->requestFile= $value;
    }

    /**
     * return control that triggered the ajax request
     * @return fily_Control
     */
    public function getTriggerControl() {
        return $this->triggerControl;
    }

    /**
     * return event that triggered the ajax request
     * @return string
     */
    public function getTriggerEvent() {
        return $this->triggerEvent;
    }

    /**
     * returns the value of the trigger control
     * @return string
     */
    public function getTriggerValue() {
        return $this->triggerValue;
    }


    /**
     * finds a control with the specific id
     * @param string $id
     * @return fily_ControlToHtml
     */
    public function getControlById($id) {
        return $this->controls->getControlById($id);
    }


    /**
     * finds a control with the specific system id
     * @param string $sid
     * @return fily_ControlToHtml
     */
    public function getControlBySid($sid) {
        return $this->controls->getControlBySid($sid);
    }


    protected $lateBindingObjects = array();

    public function XMLAddControl(fily_ControlToHtml $control) {
        $this->controls->add($control);
    }
    public function XMLAttributes(array $attributes, $innerValue) {
        foreach($attributes as $key => $value) {
            switch ($key) {
                case 'requestfile':
                    $this->setRequestFile($value);
                    break;
                case 'sid':
                    $this->setSid($value);
                    break;
                default:
                    throw new Exception('XML Convert : attribute "'. $key.'" not know for ' .  get_class($this));
                     break;
            }
        }
    }
    public function XMLCallFunction($name, array $parameters, $innerValue, fily_ControlToHtml $innerControl = null) {
        switch ($name) {
            case 'addupdatetrigger':
                $this->lateBindingObjects['addupdatetrigger'][] = $parameters;
                break;
            default :
                break;
        }
    }
    public function XMLLateBinding(fily_ControlToHtml $baseControl) {
        foreach($this->lateBindingObjects as $key => $value) {
            switch ($key) {
                case 'addupdatetrigger':
                    foreach ($this->lateBindingObjects[$key] as $parameters) {
                         $control = fily_XMLConverter::findControl($parameters['control'], $this, $baseControl);
                        if($control!=null){
                            if(!isset($parameters['executionzone'])) {
                                $this->addUpdateTrigger($control, $parameters['event']);
                            }
                            else {
                                $this->addUpdateTrigger($control, $parameters['event'],$parameters['executionzone']);
                            }
                        }
                    }
                    break;
            }
        }
    }


    public function find($expression) {
        $control = null;
        if(!fily_ExpressionHelper::isExpression($expression)) {
            //expression is an id
            $control = $this->getControlById($expression);
        }
        else {
            $expressionParts = fily_ExpressionHelper::getParts($expression) ;
            // first expression part is always empty
            if(count($expressionParts)>1) {
                switch ($expressionParts[1]) {
                    case 'after':
                        $control = fily_ExpressionHelper::after($expressionParts, $expression, $this->controls);
                        break;
                    case  'before':
                        $control = fily_ExpressionHelper::before($expressionParts, $expression, $this->controls);
                        break;
                    case 'first':
                        $control = fily_ExpressionHelper::first($expressionParts, $expression, $this->controls);
                        break;
                    case 'last':
                        $control = fily_ExpressionHelper::last($expressionParts, $expression,  $this->controls);
                        break;
                    case 'child':
                        $control = fily_ExpressionHelper::child($expressionParts, $expression, $this->controls);
                        break;
                }
            }
            // found a control and have another expressions
            if($control!=null && !empty($expression)) {
                $control = $control->find($expression);
            }
        }
        return $control;
    }
}

?>
